package com.tdcy.sys.util.sms;

import java.io.ByteArrayInputStream;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.util.Date;
import java.util.HashMap;
import java.util.Map;

import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.entity.BasicHttpEntity;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.params.BasicHttpParams;
import org.apache.http.params.HttpParams;
import org.apache.http.util.EntityUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.tdcy.framework.util.ContextUtils;
import com.tdcy.framework.util.CryptoHUtils;
import com.tdcy.framework.util.DateUtils;
import com.tdcy.framework.util.ExceptionUtils;
import com.tdcy.framework.util.JsonUtils;
import com.tdcy.framework.util.StringUtils;
import com.tdcy.sys.constant.ParamConstants;
import com.tdcy.sys.dao.ISmsChkCodeDAO;
import com.tdcy.sys.dao.ISmsRecordDAO;
import com.tdcy.sys.dao.eo.SmsChkCodeEO;
import com.tdcy.sys.dao.eo.SmsRecordEO;
import com.tdcy.sys.service.bean.SmsConfigBean;
import com.tdcy.sys.service.bean.SmsResultBean;
import com.tdcy.sys.service.bean.SmsSendBean;
import com.tdcy.sys.util.ParamUtils;
import com.tdcy.sys.util.SeqUtils;

public class SmsUtils implements Runnable {
	public static Logger logger = LoggerFactory.getLogger(SmsUtils.class);
	private SmsSendBean sbean;

	public SmsSendBean getSbean() {
		return sbean;
	}

	public void setSbean(SmsSendBean sbean) {
		this.sbean = sbean;
	}

	@Override
	public void run() {
		sendSms(sbean);
	}

	public void sendSms(SmsSendBean sbean) {
		SmsConfigBean cbean = getConfigbean();

		String timestamp = DateUtils.dateToString(new Date(), "yyyyMMddHHmmss");// 获取时间戳
		String signature;
		String result = null;
		try {
			signature = getSignature(cbean.getAccountSid(), cbean.getAuthToken(), timestamp);

			StringBuffer sb = new StringBuffer("https://");
			sb.append(cbean.getServer());
			String url = sb.append("/").append(cbean.getVersion()).append("/Accounts/").append(cbean.getAccountSid()).append("/Messages/templateSMS").append("?sig=").append(signature).toString();

			Map<String, String> m = new HashMap<String, String>();
			m.put("appId", cbean.getAppId());
			m.put("param", sbean.getParam());
			m.put("templateId", sbean.getTemplateId());
			m.put("to", sbean.getTo());

			Map<String, Object> param = new HashMap<String, Object>();
			param.put("templateSMS", m);

			HttpResponse response = post("application/json", cbean.getAccountSid(), cbean.getAuthToken(), timestamp, url, getDefaultHttpClient(cbean.getSslip(), cbean.getSslport()),
					JsonUtils.toJson(param));
			// 获取响应实体信息
			HttpEntity entity = response.getEntity();
			if (entity != null) {
				result = EntityUtils.toString(entity, "UTF-8");
			}
			// 确保HTTP响应内容全部被读出或者内容流被关闭
			EntityUtils.consume(entity);

			processResult(sbean, transferResult(result));
		} catch (Exception e) {
			logger.error("异常消息:" + ExceptionUtils.getThrowableStr(e));
			processError(sbean, e);
		}

	}

	private void processError(SmsSendBean sbean, Exception e) {
		ISmsRecordDAO smsrdao = ContextUtils.getApplicationContext().getBean(ISmsRecordDAO.class);

		// 添加短信记录
		SmsRecordEO sreo = new SmsRecordEO();
		sreo.setSmsId(SeqUtils.getMaxNo("sms_id"));
		sreo.setSmsPhone(sbean.getTo());
		sreo.setSendTime(new Date());
		String param = sbean.getParam();
		sreo.setStatus(-1);
		if (sbean.isCheckSms()) {
			sreo.setSmsType(1);
		} else {
			sreo.setSmsType(2);
		}
		sreo.setSmsContent(param);
		sreo.setTmpId(sbean.getTemplateId());
		sreo.setRespcode("-100");
		sreo.setRespmsg(e.getMessage());
		smsrdao.save(sreo);
	}

	private void processResult(SmsSendBean sbean, SmsResultBean resultBean) {
		ISmsRecordDAO smsrdao = ContextUtils.getApplicationContext().getBean(ISmsRecordDAO.class);
		ISmsChkCodeDAO ccdao = ContextUtils.getApplicationContext().getBean(ISmsChkCodeDAO.class);

		String respCode = resultBean.getRespCode();

		SmsRecordEO sreo = new SmsRecordEO();
		sreo.setSmsId(SeqUtils.getMaxNo("sms_id"));
		sreo.setSmsPhone(sbean.getTo());
		sreo.setSendTime(new Date());
		String param = sbean.getParam();
		sreo.setStatus(0);
		if (sbean.isCheckSms()) {
			sreo.setSmsType(1);
		} else {
			sreo.setSmsType(2);
		}
		sreo.setSmsContent(param);
		sreo.setTmpId(sbean.getTemplateId());
		if ("000000".equals(respCode)) {
			String templateSMS = (String) resultBean.getParam("templateSMS");
			Map<String, Object> templateSMSMap = JsonUtils.toMap(templateSMS);
			String smsBackId = StringUtils.getString(templateSMSMap, "smsId");
			sreo.setBacksmsid(smsBackId);
		}
		sreo.setRespcode(respCode);
		sreo.setRespmsg(resultBean.getFailure());
		smsrdao.save(sreo);

//		if (!"000000".equals(respCode)) {
//			String failure = resultBean.getFailure() + "(" + respCode + ")";
//			throw new QuickuException(failure);
//		}

		if (sbean.isCheckSms()) {
			SmsChkCodeEO sceo = new SmsChkCodeEO();
			sceo.setCcId(sbean.getCcId());
			sceo.setCcCodevalue(sbean.getCheckCode());
			sceo.setSendTime(sbean.getSendTime());
			sceo.setSmsId(sreo.getSmsId());
			ccdao.save(sceo);
		}
	}

	/**
	 * 获取签名
	 * 
	 * @param accountSid
	 * @param authToken
	 * @param timestamp
	 * @return
	 * @throws Exception
	 */
	public String getSignature(String accountSid, String authToken, String timestamp) throws Exception {
		String sig = accountSid + authToken + timestamp;
		String signature = CryptoHUtils.md5(sig);
		return signature;
	}

	/**
	 * 获取客户端
	 * 
	 * @param sslIP
	 * @param sslPort
	 * @return
	 */
	public DefaultHttpClient getDefaultHttpClient(String sslIP, int sslPort) {
		DefaultHttpClient httpclient = null;
		try {
			SSLHttpClient chc = new SSLHttpClient();
			httpclient = chc.registerSSL(sslIP, "TLS", sslPort, "https");
			HttpParams hParams = new BasicHttpParams();
			hParams.setParameter("https.protocols", "SSLv3,SSLv2Hello");
			httpclient.setParams(hParams);
		} catch (KeyManagementException e) {
			logger.error(ExceptionUtils.getThrowableStr(e));
		} catch (NoSuchAlgorithmException e) {
			logger.error(ExceptionUtils.getThrowableStr(e));
		}
		return httpclient;
	}

	/**
	 * 发送请求
	 * 
	 * @param cType
	 * @param accountSid
	 * @param authToken
	 * @param timestamp
	 * @param url
	 * @param httpclient
	 * @param body
	 * @return
	 * @throws Exception
	 */
	public HttpResponse post(String cType, String accountSid, String authToken, String timestamp, String url, DefaultHttpClient httpclient, String body) throws Exception {
		HttpPost httppost = new HttpPost(url);
		httppost.setHeader("Accept", cType);
		httppost.setHeader("Content-Type", cType + ";charset=utf-8");
		String src = accountSid + ":" + timestamp;
		String auth = CryptoHUtils.base64Encoder(src);
		httppost.setHeader("Authorization", auth);
		BasicHttpEntity requestBody = new BasicHttpEntity();
		requestBody.setContent(new ByteArrayInputStream(body.getBytes("UTF-8")));
		requestBody.setContentLength(body.getBytes("UTF-8").length);
		httppost.setEntity(requestBody);
		// 执行客户端请求
		HttpResponse response = httpclient.execute(httppost);
		return response;
	}

	public static SmsResultBean transferResult(String result) {
		SmsResultBean srb = new SmsResultBean();
		Map<String, Object> resultParam = JsonUtils.toMap(result);
		srb.setResultParam((Map<String, Object>) resultParam.get("resp"));
		return srb;
	}

	/**
	 * 获取sms配置
	 * 
	 * @return
	 */
	protected SmsConfigBean getConfigbean() {
		String server = ParamUtils.getParamValue(ParamConstants.SMS_SERVER);
		String version = ParamUtils.getParamValue(ParamConstants.SMS_VERSION);
		String accountSid = ParamUtils.getParamValue(ParamConstants.SMS_ACCOUNTSID);
		String authToken = ParamUtils.getParamValue(ParamConstants.SMS_AUTHTOKEN);
		String appId = ParamUtils.getParamValue(ParamConstants.SMS_APPID);
		String sms_http_ssl_ip = ParamUtils.getParamValue(ParamConstants.SMS_HTTP_SSL_IP);
		String sms_http_ssl_port = ParamUtils.getParamValue(ParamConstants.SMS_HTTP_SSL_PORT);

		SmsConfigBean cbean = new SmsConfigBean();
		cbean.setAccountSid(accountSid);
		cbean.setAppId(appId);
		cbean.setAuthToken(authToken);
		cbean.setServer(server);
		cbean.setSslip(sms_http_ssl_ip);
		cbean.setSslport(Integer.parseInt(sms_http_ssl_port));
		cbean.setVersion(version);
		return cbean;
	}

	public static void main(String[] args) {
		// String accountSid = "59cba09df3c8d07429c08f0799442e93";
		// String authToken = "544d396af7190a27786d16e5e054c520";
		// String appId = "caa89d9bf1654f02829f10524e2db7b0";
		// String server = "api.ucpaas.com";
		// String sslip = "0";
		// int sslport = 443;
		// String version = "2014-06-30";
		//
		// String templateId = "11433";
		// String to = "15367811408";
		// String param = "1234,1";
		//
		// SmsSendBean sbean = new SmsSendBean();
		// sbean.setParam(param);
		// sbean.setTemplateId(templateId);
		// sbean.setTo(to);
		// String s = sendSms(sbean);
		// System.out.println(s);

		String s = "{\"resp\": {\"respCode\": \"000000\",\"failure\" : 1,\"templateSMS\" : {\"createDate\"  : 20140623185016,\"smsId\"       : \"f96f79240e372587e9284cd580d8f953\"}}}";

		System.out.println(JsonUtils.toJson(transferResult(s)));
	}

}
